package org.chen.aao.ai.service.chat;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.theokanning.openai.completion.chat.ChatCompletionRequest;
import com.theokanning.openai.completion.chat.ChatMessage;
import com.theokanning.openai.service.OpenAiService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.chen.aao.ai.feign.SubsServiceClient;
import org.chen.aao.ai.mapper.ChatHistoryMapper;
import org.chen.aao.ai.mapper.TranslateHistoryMapper;
import org.chen.aao.ai.service.IChatService;
import org.chen.aao.common.ai.dto.ChatHistoryResponse;
import org.chen.aao.common.ai.dto.ChatRequest;
import org.chen.aao.common.ai.dto.ChatResponse;
import org.chen.aao.common.ai.dto.TranslateHistoryResponse;
import org.chen.aao.common.ai.entity.ChatHistory;
import org.chen.aao.common.ai.entity.TranslateHistory;
import org.chen.aao.common.exception.AIServiceException;
import org.chen.aao.common.exception.QuotaExceededException;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Slf4j
@Service
@RequiredArgsConstructor
public class ChatServiceImpl implements IChatService {

    private final ChatHistoryMapper chatHistoryMapper;
    private final OpenAiService openAiService;
    private final RedisTemplate<String, Object> redisTemplate;
    private final SubsServiceClient subsServiceClient;

    @Override
    // 获取聊天历史
    public ChatHistoryResponse getChatHistory(Long userId, String conversationId, int page, int size) {
        Page<ChatHistory> pageRequest = new Page<>(page, size);
        QueryWrapper<ChatHistory> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId);

        if (conversationId != null && !conversationId.isEmpty()) {
            queryWrapper.eq("conversation_id", conversationId);
        }

        queryWrapper.orderByDesc("created_at");

        Page<ChatHistory> historyPage = chatHistoryMapper.selectPage(pageRequest, queryWrapper);

        List<ChatHistoryResponse.ChatMessage> messages = historyPage.getRecords().stream()
                .map(history -> ChatHistoryResponse.ChatMessage.builder()
                        .id(String.valueOf(history.getId()))
                        .conversationId(history.getConversationId())
                        .userMessage(history.getUserMessage())
                        .aiReply(history.getAiReply())
                        .createdAt(history.getCreatedAt())
                        .tokensUsed(history.getTokensUsed())
                        .build())
                .collect(Collectors.toList());

        return ChatHistoryResponse.builder()
                .messages(messages)
                .total((int) historyPage.getPages())
                .build();
    }

    // AI聊天功能
    public ChatResponse chat(ChatRequest request, Long userId) {
        LocalDate today = LocalDate.now();
        String todayKey = String.format("usage:daily:%d:%s", userId, today);
        String monthKey = String.format("usage:monthly:%d:%s", userId, today.withDayOfMonth(1));

        // 检查用户配额
        Object dailyUsageObj = redisTemplate.opsForHash().get(todayKey, "chat");
        int dailyUsage = dailyUsageObj != null ? Integer.parseInt(dailyUsageObj.toString()) : 0;

        if (dailyUsage >= getMaxDailyChats(userId)) {
            throw new QuotaExceededException("每日聊天次数已达上限");
        }

        try {
            // 构建对话历史
            List<ChatMessage> messages = buildChatHistory(request.getConversationId(), userId);
            messages.add(new ChatMessage("user", request.getMessage()));

            // 调用OpenAI API
            ChatCompletionRequest completionRequest = ChatCompletionRequest.builder()
                    .model(request.getModel() != null ? request.getModel() : "gpt-4o-mini")
                    .messages(messages)
                    .maxTokens(2048)
                    .temperature(0.7)
                    .build();

            var completion = openAiService.createChatCompletion(completionRequest);
            String reply = completion.getChoices().get(0).getMessage().getContent();

            // 保存聊天记录
            ChatHistory history = new ChatHistory();
            history.setUserId(userId);
            history.setConversationId(request.getConversationId());
            history.setUserMessage(request.getMessage());
            history.setAiReply(reply);
            history.setModel(request.getModel());
            history.setTokensUsed(completion.getUsage().getTotalTokens());
            chatHistoryMapper.insert(history);

            // 更新配额
            updateUsageStats(todayKey, monthKey, (int) completion.getUsage().getTotalTokens());

            return ChatResponse.builder()
                    .reply(reply)
                    .conversationId(history.getConversationId())
                    .usage(ChatResponse.Usage
                            .builder()
                            .tokens(completion.getUsage().getTotalTokens()).
                            build())
                    .build();

        } catch (Exception e) {
            log.error("Chat error for user {}: {}", userId, e.getMessage());
            throw new AIServiceException("聊天服务暂时不可用");
        }
    }

    // 更新使用统计
    private void updateUsageStats(String todayKey, String monthKey, Integer tokens) {
        // 更新今日统计
        redisTemplate.opsForHash().increment(todayKey, "chat", 1);
        redisTemplate.opsForHash().increment(todayKey, "tokens", tokens);
        redisTemplate.expire(todayKey, 1, TimeUnit.DAYS);

        // 更新月度统计
        redisTemplate.opsForHash().increment(monthKey, "chat", 1);
        redisTemplate.opsForHash().increment(monthKey, "tokens", tokens);
        // 月度统计设置较长的过期时间，比如35天
        redisTemplate.expire(monthKey, 35, TimeUnit.DAYS);
    }

    // 构建聊天历史
    private List<ChatMessage> buildChatHistory(String conversationId, Long userId) {
        if (conversationId == null || conversationId.isEmpty()) {
            conversationId = UUID.randomUUID().toString();
        }

        List<ChatHistory> history = chatHistoryMapper.selectList(
                new QueryWrapper<ChatHistory>()
                        .eq("user_id", userId)
                        .eq("conversation_id", conversationId)
                        .orderByAsc("created_at")
                        .last("LIMIT 10")
        );

        List<ChatMessage> messages = new ArrayList<>();
        for (ChatHistory h : history) {
            messages.add(new ChatMessage("user", h.getUserMessage()));
            messages.add(new ChatMessage("assistant", h.getAiReply()));
        }

        return messages;
    }

    // 获取用户配额限制
    private int getMaxDailyChats(Long userId) {
        // 根据用户订阅等级返回不同配额
        String subscriptionLevel = getSubscriptionLevel(userId);
        return switch (subscriptionLevel) {
            case "PREMIUM" -> 1000;
            case "BASIC" -> 100;
            default -> 10;
        };
    }

    // 获取订阅等级
    private String getSubscriptionLevel(Long userId) {
        String cacheKey = "user:subscription:" + userId;
        String level = (String) redisTemplate.opsForValue().get(cacheKey);
        if (level == null) {
            level = subsServiceClient.getSubscriptionStatusById(userId).getData().getPlan();
            redisTemplate.opsForValue().set(cacheKey, level, 1, TimeUnit.HOURS);
        }
        return level;
    }
}
